#include "StdAfx.h"
#include "ConfigurationManager.h"
#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_print.hpp"
#include "rapidxml/rapidxml_utils.hpp"

using namespace rapidxml;

CConfigurationManager::CConfigurationManager(void)
{
	m_uAutoSniffingFileSizeLowerBound = 1024000; // 1 MB
	CString strFlvExt = _T("flv");
	CString strFlvExt2 = _T("mp4");
	CString strFlvExt3 = _T("hlv");
	m_lstAutoSniffingFileExt.AddTail(strFlvExt);
	m_lstAutoSniffingFileExt.AddTail(strFlvExt2);
	m_lstAutoSniffingFileExt.AddTail(strFlvExt3);
	TCHAR strBuffer[2048] = {0};
	GetCurrentDirectory(2048, strBuffer);
	m_strDefaultDownloadDir = strBuffer;
	m_strDefaultDownloadDir = m_strDefaultDownloadDir.TrimRight(_T("\\"));
}


CConfigurationManager::~CConfigurationManager(void)
{
}

BOOL CConfigurationManager::LoadConfig(CString strFilepath)
{
	USES_CONVERSION;
	try
	{
		file<> fdoc(W2A(strFilepath));
		xml_document<> doc;
		doc.parse<0>(fdoc.data());

		xml_node<>* root = doc.first_node();
		if(root != NULL && 
			stricmp(root->name(), STR_CONFIG) == 0)
		{
			// We get the root
			xml_node<>* nodeSniffFileSizeLB = root->first_node(STR_AUTOSNIFFINGFILESIZELBOUND);
			if(nodeSniffFileSizeLB != NULL)
			{
				m_uAutoSniffingFileSizeLowerBound = atoi(nodeSniffFileSizeLB->value());
			}

			xml_node<>* nodeSniffFileExt = root->first_node(STR_AUTOSNIFFINGFILEEXT);
			if(nodeSniffFileExt != NULL)
			{
				m_lstAutoSniffingFileExt.RemoveAll();
				xml_node<>* nodeExt = nodeSniffFileExt->first_node(STR_FILEEXT);
				while(nodeExt != NULL)
				{
					CString strExt = A2W(nodeExt->value());
					m_lstAutoSniffingFileExt.AddTail(strExt);
					nodeExt = nodeExt->next_sibling(STR_FILEEXT);
				}
			}

			xml_node<>* nodeDefaultDownloadDir = root->first_node(STR_DEFAULTDOWNLOADINGDIR);
			if(nodeDefaultDownloadDir != NULL)
			{
				m_strDefaultDownloadDir = A2W(nodeDefaultDownloadDir->value());
				m_strDefaultDownloadDir = m_strDefaultDownloadDir.TrimRight(_T("\\"));
			}
		}
		
		return TRUE;
	}
	catch (std::exception ex)
	{
		return FALSE;
	}
}

BOOL CConfigurationManager::SaveConfig(CString strFilepath)
{
	USES_CONVERSION;

	xml_document<> doc;
	xml_node<> *root = doc.allocate_node(node_element, STR_CONFIG);
	doc.append_node(root);

	CHAR strBuff[10] = {0};
	itoa(m_uAutoSniffingFileSizeLowerBound, strBuff, 10);
	xml_node<> *nodeSniffFileSizeLB = doc.allocate_node(node_element, STR_AUTOSNIFFINGFILESIZELBOUND, strBuff);
	root->append_node(nodeSniffFileSizeLB);
	
	xml_node<> *nodeSniffFileExt = doc.allocate_node(node_element, STR_AUTOSNIFFINGFILEEXT);
	POSITION pos = m_lstAutoSniffingFileExt.GetHeadPosition();
	while(pos != NULL)
	{
		CString strExt = m_lstAutoSniffingFileExt.GetNext(pos);
		xml_node<> *nodeExt = doc.allocate_node(node_element, STR_FILEEXT, W2A(strExt));
		nodeSniffFileExt->append_node(nodeExt);
	}
	root->append_node(nodeSniffFileExt);

	xml_node<>* nodeDefaultDownloadDir = doc.allocate_node(node_element, STR_DEFAULTDOWNLOADINGDIR, W2A(m_strDefaultDownloadDir));
	root->append_node(nodeDefaultDownloadDir);

	// Write into file
	std::ofstream xmlOutput(strFilepath);
	xmlOutput<<doc;
	xmlOutput.close();

	return TRUE;
}

BOOL CConfigurationManager::SniffFileOrNot(CString strFilename)
{
	// Get the extension of file
	INT nLastPosOfQuestionMark = -1;
	nLastPosOfQuestionMark = strFilename.ReverseFind(_T('?'));
	if(nLastPosOfQuestionMark > -1)
	{
		strFilename = strFilename.Mid(0, nLastPosOfQuestionMark);
	}
	INT nLastPosOfDot = strFilename.ReverseFind(_T('.'));
	CString strExt = strFilename.Right(strFilename.GetLength() - nLastPosOfDot - 1);

	POSITION pos = m_lstAutoSniffingFileExt.GetHeadPosition();
	while(pos != NULL)
	{
		CString strExtFilter = m_lstAutoSniffingFileExt.GetNext(pos);
		if(!strExtFilter.TrimLeft(_T('.')).CompareNoCase(strExt))
		{
			return TRUE;
		}
	}

	return FALSE;
}

BOOL CConfigurationManager::SniffFileOrNot(DWORD uFileSize)
{
	return uFileSize >= m_uAutoSniffingFileSizeLowerBound;
}

VOID CConfigurationManager::GetDefaultDownloadDir(CString& strPath)
{
	strPath = m_strDefaultDownloadDir;
}